#include "userlib.h"

void gettracedtasks(vector<long> *v)
{
	char line[20];
	long pid;
	FILE *f;
	int firstline=1;
	
	f = fopen("/proc/linalter", "r");
	if(f == NULL)
		die("/proc/linalter");
	while(fgets(line, sizeof(line)-1, f) != NULL){
		if(firstline){ //ignore the first line. The first line is whether current process is altered.
			firstline=0;
			continue;
		}
		sscanf(line, "%ld", &pid);
		v->push_back(pid);
	}
	fclose(f);
	sort(v->begin(), v->end());
}

static void waituntilstopped(pid_t pid)
{
	char buffer[100];
	char line[100];
	char t;
	FILE *f;
	
	sprintf(buffer, "/proc/%ld/status", (long)pid);
	while(1){
		f = fopen(buffer, "r");
		if(f==0) /* Task Ended */
			return; 
		if(fgets(line, sizeof(line)-1, f)){
			if(fgets(line, sizeof(line)-1, f)){
				sscanf(line, "%*s %c", &t);
				/*  static const char *task_state_array[] = {
						"R (running)",
						"S (sleeping)",
						"D (disk sleep)",
						"T (stopped)",
						"T (tracing stop)",
						"Z (zombie)",
						"X (dead)"
					}; */
				if(t!='R' && t!='S' && t!='D') return;
			}else die("fgets");
		}else die("fgets");
		fclose(f);
		usleep(10*1000); /* sleep 10 milliseconds */
	}
}

void stoptask()
{
	vector<long> tasks;
	unsigned int i;
	long pid;
	
	gettracedtasks(&tasks);
	for(i=0; i<tasks.size(); i++){
		pid = tasks[i];
		if( kill(pid, SIGSTOP) == -1)
			die("kill SIGSTOP");
		waituntilstopped(pid);
	}
}

void continuetask()
{
	vector<long> tasks;
	unsigned int i;
	long pid;
	
	gettracedtasks(&tasks);
	for(i=0; i<tasks.size(); i++){
		pid = tasks[i];
		if( kill(pid, SIGCONT) == -1)
			die("kill SIGCONT");
	}
}
